跳到主要内容

故障演练和恢复

故障演练常识

nameNode下的文件说明。

drwx------ 2 bigdata bigdata 4096 Oct 28 13:22 current

-rw-rw-r-- 1 bigdata bigdata 12 Oct 28 14:08 in_use.lock (集群启动的时候才有这个文件)

current在两个namenode的文件有什么不同?

master1:

  • namenode:
edits_0000000000000001698-0000000000000001699
edits_0000000000000001700-0000000000000001700
edits_inprogress_0000000000000001701
fsimage_0000000000000001498
fsimage_0000000000000001498.md5
fsimage_0000000000000001655
fsimage_0000000000000001655.md5
seen_txid (记录执行到事务的位置)
VERSION (主节点和从节点文件内容一样的)

[bigdata@master1 current]$ cat seen_txid (正在处理的事物id,作为下一次重启时起到一个记录的作用)
1700

[bigdata@master1 current]$ cat VERSION
#Sat Oct 28 12:23:57 CST 2023
namespaceID=233096029
clusterID=CID-4b274b14-a491-4342-93ac-8187401bbf63
cTime=1698396823122
storageType=NAME_NODE
blockpoolID=BP-574146300-10.240.8.68-1698396823122
layoutVersion=-65

master2:

  • namenode:
edits_inprogress_0000000000000001492
fsimage_0000000000000001496
fsimage_0000000000000001496.md5
fsimage_0000000000000001655
fsimage_0000000000000001655.md5
seen_txid
VERSION

[bigdata@master2 current]$ cat seen_txid
1492

[bigdata@master2 current]$ cat VERSION
#Sat Oct 28 13:22:04 CST 2023
namespaceID=233096029
clusterID=CID-4b274b14-a491-4342-93ac-8187401bbf63
cTime=1698396823122
storageType=NAME_NODE
blockpoolID=BP-574146300-10.240.8.68-1698396823122
layoutVersion=-65

edits_inprogress_0000000000000001701 是Hadoop中的一个编辑日志文件(Edit Log File)。 Hadoop的NameNode维护了一个编辑日志,它记录了对HDFS命名空间的操作,例如文件的创建、删除和重命名。编辑日志用于恢复HDFS的一致性,以及在NameNode出现故障时进行恢复。 当NameNode写入编辑日志时,实际上是在一个活动的编辑日志文件中进行写入。当该文件达到一定大小时,NameNode会创建一个新的编辑日志文件,并将活动日志文件标记为“in-progress”(即edits_inprogress)。标记为“in-progress”的日志文件表示该文件仍在写入中,尚未被完整地合并到持久化的编辑日志文件中。 一旦“in-progress”文件达到一定大小或达到一定时间间隔,NameNode会将其合并到持久化的编辑日志文件中,并且“in-progress”标记将被移除。在这个过程中,旧的“in-progress”文件会被重命名为edits_0000000000000001701(在这里是示例文件名),并表示已完成的操作。 因此,edits_inprogress_0000000000000001701 文件表示一个正在被写入的活动编辑日志文件,其中记录了对HDFS命名空间的操作

seen_txid 文件是Hadoop中的一个元数据文件,用于跟踪已经处理的事务ID(Transaction ID)。在Hadoop的NameNode中,事务ID用于标识对HDFS命名空间的每个操作。每当NameNode处理一个操作时,它会为该操作分配一个唯一的事务ID。这些事务ID按顺序递增,并且在编辑日志(Edit Log)中记录。seen_txid 文件记录了NameNode已经处理的最新事务ID。它用于在NameNode启动时确定从哪个事务ID开始读取编辑日志,以便进行恢复和重放操作。通过读取seen_txid 文件,NameNode可以确定上次正常关闭后处理的最后一个事务ID,从而继续处理后续的事务。当NameNode处理一个新的事务时,它会更新seen_txid 文件,将其中记录的最新事务ID更新为当前处理的事务ID。这样,在下一次启动时,NameNode就知道从哪个事务ID开始读取编辑日志。因此,seen_txid 文件在Hadoop中起着重要的作用,用于记录和跟踪已经处理的事务ID,以确保正确的恢复和重放操作。

master1和master2的jn有什么不同。

  • master1

jn

[bigdata@master1 bigdatacluster]$ ls current edits.sync

edits.sync 都是空的,我们对比下current。

edits_0000000000000001702-0000000000000001703
edits_inprogress_0000000000000001704
last-promised-epoch
last-writer-epoch
paxos
VERSION

[bigdata@master1 current]$ cat last-promised-epoch
8

[bigdata@master1 current]$ cat last-writer-epoch
8

[bigdata@master1 current]$ cat VERSION
#Fri Oct 27 16:53:43 CST 2023
namespaceID=233096029
clusterID=CID-4b274b14-a491-4342-93ac-8187401bbf63
cTime=1698396823122
storageType=JOURNAL_NODE
layoutVersion=-65
  • master2:

jn

[bigdata@master2 bigdatacluster]$ ls current edits.sync

edits_0000000000000001702-0000000000000001703
edits_inprogress_0000000000000001704
last-promised-epoch
last-writer-epoch
paxos
VERSION

[bigdata@master2 current]$ cat last-promised-epoch
8

[bigdata@master2 current]$ cat last-writer-epoch
8

[bigdata@master2 current]$ cat VERSION
#Fri Oct 27 16:53:43 CST 2023
namespaceID=233096029
clusterID=CID-4b274b14-a491-4342-93ac-8187401bbf63
cTime=1698396823122
storageType=JOURNAL_NODE
layoutVersion=-65

结论

可以看到,master1和master2的元数据文件基本一致,也就是说,只要元数据有备份一份,那么HDFS就可以正常工作。namenode直接唯一有点不同的就是,从的namenode的edits_inprogress_00000000000日志要慢与主节点。jn的所有的元数据都是一致的

也就是说,只要有一份namenode,一份jn的元数据,先停掉hadoop,然后把已有的namenode的元数据,全部复制给从节点的namenode,把有的jn数据复制给其他的jn,那么集群就能够恢复正常。还有就是如果一台namenode实在救不活了,那么删除挂掉的namenode元数据直接重新加入集群hdfs namenode -bootstrapStandby

故障演练

我们知道了对应的配置文件作用以后,那么我们实际演练一波。

先说明下现在的环境

以下是您要求的表格形式:

主机规划设置主机名角色
10.240.8.68master1NameNode、DataNode、ResourceManager、NodeManager
10.240.8.229master2SecondaryNameNode、DataNode、NodeManager
10.240.8.185node1DataNode、NodeManager

还有下面的配置

    <property>
<!--指定 hadoop 集群存储临时文件的目录-->
<name>hadoop.tmp.dir</name>
<value>/datadrive</value>
</property>
<!-- NameNode数据存储目录 -->
<property>
<name>dfs.namenode.name.dir</name>
<value>file://${hadoop.tmp.dir}/name</value>
</property>
<!-- DataNode数据存储目录 -->
<property>
<name>dfs.datanode.data.dir</name>
<value>file://${hadoop.tmp.dir}/data</value>
</property>
<!-- JournalNode数据存储目录 -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>${hadoop.tmp.dir}/jn</value>
</property>

如果一台namenode数据被删除以后,怎么恢复集群?

故障模拟

如上配置,只要我们删除了master2上面的/datadrive,那么相当于一次删除了一个datanode的数据和一个namenode的数据。

rm -rf /datadrive/*

删除以后程序还是一个运行的状态

[bigdata@node1 ~]$ hdfs haadmin -getAllServiceState
master1:8020 active
master2:8020 standby
[bigdata@node1 ~]$ yarn rmadmin -getAllServiceState
master1:8033 active
master2:8033 standby

故障恢复方式一

启动hdfs的安全模式。

<!-- 打开 -->
hdfs dfsadmin -safemode enter

把master1的namenode信息和jn信息同步到master2。

./masterxsync.sh /datadrive/name/ /datadrive/jn/

hdfs dfsadmin -saveNamespace

[bigdata@master2 name]$ hdfs dfsadmin -saveNamespace
Save namespace successful for master1/10.240.8.68:8020
Save namespace failed for master2/10.240.8.229:8020
saveNamespace: No image directories available!

<!-- 重启hadoop集群 -->

./hadoop_server.sh stop
./hadoop_server.sh start

[bigdata@master1 shell]$ yarn rmadmin -getAllServiceState
master1:8033 standby
master2:8033 active
[bigdata@master1 shell]$ hdfs haadmin -getAllServiceState
master1:8020 active
master2:8020 standby


hdfs dfsadmin -safemode enter

hdfs dfsadmin -saveNamespace, 如下,可以看到执行成功了,命令的作用是把namenode的元数据信息保存到磁盘上。形成一个新的fsimage。

[bigdata@master1 shell]$ hdfs dfsadmin -saveNamespace
Save namespace successful for master1/10.240.8.68:8020
Save namespace successful for master2/10.240.8.229:8020

<!-- 关闭 -->
hdfs dfsadmin -safemode leave

检查下磁盘的健康程度,应该我们刚才删除了一个datanode节点,界面上面看到有一个datanode没有起来。

那我们手动启动下。并且查看对应的datanode日志。

./hadoop-daemon.sh start datanode

tail -f hadoop-bigdata-datanode-master2.log

报错如下

2023-10-28 12:31:44,524 ERROR org.apache.hadoop.hdfs.server.datanode.DataNode: Initialization failed for Block pool <registering> (Datanode Uuid unassigned) service to master1/10.240.8.68:8020. Exiting. 
java.io.IOException: All specified directories have failed to load.

那我们删除rm -rf data/

然后重新启动

./hadoop-daemon.sh start datanode

问题解决了。

然后跑一个mr程序

hadoop jar /home/bigdata/module/hadoop-3.2.3/share/hadoop/mapreduce/hadoop-mapreduce-examples-3.2.3.jar wordcount  -Dmapreduce.job.queuename=default /data /output

成功运行,问题解决。